var path = require('path');
var express = require('express');
var router = express.Router();
var xlsx = require('node-xlsx');
var glob = require('glob');
var fs = require('fs');

var manageSheets = xlsx.parse(path.join(__dirname, '../data/manage/data.xlsx'));
var controlSheets = xlsx.parse(path.join(__dirname, '../data/control/data.xlsx'));

var manageResult = [];
var controlResult = [];

var span3MonthMax = 0;
var spanYearMax = 0;
var targetResult = [];

var manageData = manageSheets[0]['data'];
var controlData = controlSheets[0]['data'];

var targetKeys = ['收缩压', '舒张压', '体重(kg)', '钾', '钠', '氯', '钙', '磷', 'PTH', 'ALP',
	'WBC(白细胞计数)', 'RBC(红细胞计数)', 'Hb(血红蛋白)', 'PLT（血小板计数）', 'ALT(谷丙转氨酶)',
	'AST(谷草转氨酶)', 'TP(总蛋白)', 'ALB(白蛋白)', 'GLB(球蛋白)', 'BUN(尿素)', 'Scr(血肌酐)',
	'UA(尿酸)', 'GLU(血糖)', 'TC(总胆固醇)', 'TG(甘油三酯)', '高密度脂蛋白（HDL-C）', '低密度脂蛋白（LDL-C）',
	'HSCRP', '糖化血红蛋白（HbA1C）', '尿蛋白', '尿红细胞', '尿白细胞', '24h尿蛋白', '尿肌酐／尿蛋白']

var visitTimeIndexList = [];
manageData[0].forEach((item, index) => {
	if(item.includes('次访视时间')) {
		visitTimeIndexList.push(index)
	}
})

var	targetKeysManageMap = {
	'血常规.白细胞计数': 'WBC(白细胞计数)',
	'血常规.红细胞计数': 'RBC(红细胞计数)',
	'血常规.血红蛋白': 'Hb(血红蛋白)',
	'血常规.血小板': 'PLT（血小板计数）',
	'血清丙氨酸氨基转氨酶': 'ALT(谷丙转氨酶)',
	'天门冬氨酸氨基转氨酶': 'AST(谷草转氨酶)',
	'总蛋白': 'TP(总蛋白)',
	'血生化.白蛋白': 'ALB(白蛋白)',
	'血生化.球蛋白': 'GLB(球蛋白)',
	'血生化.尿素': 'BUN(尿素)',
	'血生化.肌酐': 'Scr(血肌酐)',
	'血生化.尿酸': 'UA(尿酸)',
	'血生化.糖(mmol/L)': 'GLU(血糖)',
	'血生化.总胆固醇': 'TC(总胆固醇)',
	'血生化.甘油三脂': 'TG(甘油三酯)',
	'高密度脂蛋白胆固醇': '高密度脂蛋白（HDL-C）',
	'低密度脂蛋白胆固醇': '低密度脂蛋白（LDL-C）',
	'血生化.糖化血红蛋白': '糖化血红蛋白（HbA1C）',
	'尿液检查.尿蛋白': '尿蛋白',
	'尿液检查.红细胞计数': '尿红细胞',
	'尿液检查.白细胞计数': '尿白细胞',
	'微量蛋白/肌酐': '尿肌酐／尿蛋白'
}

var targetKeysManageValues = Object.values(targetKeysManageMap)
targetKeys.forEach(item => {
	if(item == 'PTH' || item == 'ALP' || item == 'HSCRP') {
		return
	}

	if(!targetKeysManageValues.includes(item)) {
		targetKeysManageMap[item] = item
	}
})

const KEYS_MAP_MANAGE = {
	'姓名': 2,
	'年龄': 4,
	'性别': 3,
	'糖尿病': 8,
	'高血压': 9,
	'身高': 10,
	'体重': 11,
	'序号': 13,
}

const LAB_KEYS_MANAGE = {
	'肌酐': '.血生化.肌酐',
	'尿酸': '血生化.尿酸',
	'尿素氮': '血生化.尿素',
	'血红蛋白': '血常规.血红蛋白',
	'白细胞计数': '血常规.白细胞计数',
	'尿蛋白': '理化检查结果.尿液检查.尿蛋白',
}

function getManageRecentVisit(date, person) {
	
	let dateList = visitTimeIndexList.map(item => {
		if(Number.isNaN(+new Date(person[item]))) {
			return {
				index: item,
				date: null
			}
		}
		return {
			index: item,
			date: new Date(person[item]),
		}
	})


	return dateList.sort((a, b) => {
		return Math.abs(a.date - date) - Math.abs(b.date - date)
	})

	// let diffList = dateList.map(item => {
	// 	if(item == null) {
	// 		return Infinity
	// 	}

	// 	return Math.abs(new Date(item) - new Date(date))
	// })
	// let min = Math.min.apply(null, diffList)

	// const res = []
	// diffList.forEach((item, index) => {
	// 	if(item === min) {
	// 		res.push(index)
	// 	}
	// })
	
	// if(res.length === 1) {
	// 	return visitTimeIndexList[res[0]]
	// }

	// if(dateList[res[0]] < new Date(date)) {
	// 	return visitTimeIndexList[res[0]]
	// }
	// return visitTimeIndexList[res[1]]
}

function calcManageEgfrSlope(person, title, age, birthDate, ti) {
	let baseDate = new Date(1900, 0, person[1] - 1)
	let dateList = visitTimeIndexList.map(index => {
		if(!person[index]) {
			return
		}
		if(Number.isNaN(+new Date(person[index]))) {
			return
		}

		let date = new Date(person[index])
		if(date < baseDate) {
			return
		}

		return {
			index,
			date,
		}
	})

	dateList = dateList.filter(item => item != null)

	dateList = dateList.map(item => {
		let index = -1
		let titleTemp = title.slice(item.index)

		titleTemp.some((titleItem, j) => {
			if(titleItem.includes('.血生化.肌酐')) {
				index = j
				return true
			}

			return false
		})

		return { 
			...item,
			'肌酐': person[item.index + index]
		}
	})

	dateList = dateList.filter(item => item['肌酐'] != null)
	
	let egfrList = dateList.map(item => {
		let age = item.date.getFullYear() - birthDate.getFullYear()
		let egfrObj = {...item, '性别': person[3], '年龄': age}
		calculateGFR(egfrObj)
		return egfrObj
	})

	egfrList = egfrList.map(item => {
		return {
			y: item.GFR,
			x: calcDiffDays(item.date, baseDate) / 365
		}
	})

	return {
		...calcEquationFactor(egfrList, ti),
		GFR_Latest: +egfrList[egfrList.length - 1].y,
		scrList: dateList.map(item => ({
			scr: item['肌酐'],
			date: calcDiffDays(item.date, baseDate) / 365
		}))
	}
}

function calcEquationFactor(data, ti) {
	if(data.length < 2) {
		return {
			k: '--',
			b: '--',
			error: true,
		}
	}

	let xSum = 0
	let ySum = 0
	let xySum = 0
	let x2Sum = 0

	data.forEach(item => {
		xSum += item.x
		ySum += +item.y
		xySum += item.x * item.y
		x2Sum += item.x * item.x
	})

	let xAverage = xSum / data.length
	let yAverage = ySum / data.length

	let k = (xySum - data.length * xAverage * yAverage) / (x2Sum - data.length * xAverage * xAverage)
	let b = yAverage - k * xAverage

	return {
		k,
		b,
	}
}

function getManageVisitList(person, baseDate) {
	let dateList = []
	visitTimeIndexList.forEach(item => {
		if(!person[item]) {
			return
		}
		if(Number.isNaN(+new Date(person[item]))) {
			return
		}
		if(new Date(person[item]) < baseDate) {
			return
		}
		dateList.push(new Date(person[item]))
	})

	return dateList
}

function calcDiffDays(d1, d2) {
	return Math.floor(Math.abs(d1 - d2) / (24 * 3600 * 1000))
}

function calcManageHbUaAverage(person, title) {
	let baseDate = new Date(1900, 0, person[1] - 1)
	let dateList = visitTimeIndexList.map(index => {
		if(!person[index]) {
			return
		}

		if(Number.isNaN(+new Date(person[index]))) {
			return
		}

		let date = new Date(person[index])
		if(date < baseDate) {
			return
		}

		return index
	})

	let hbList = dateList.map(item => {
		let index = -1
		let titleTemp = title.slice(item)

		titleTemp.some((titleItem, j) => {
			if(titleItem.includes('血常规.血红蛋白')) {
				index = j
				return true
			}

			return false
		})

		return person[item + index]
	})

	hbList = hbList.filter(item => item != null)

	let uaList = dateList.map(item => {
		let index = -1
		let titleTemp = title.slice(item)

		titleTemp.some((titleItem, j) => {
			if(titleItem.includes('血生化.尿酸')) {
				index = j
				return true
			}

			return false
		})

		return person[item + index]
	})

	uaList = uaList.filter(item => item != null)

	return {
		uaAverage: uaList.reduce((prev, current) => prev + current, 0) / uaList.length,
		hbAverage: hbList.reduce((prev, current) => prev + current, 0) / hbList.length,
	}
}

function getManageLatestVisit(person, baseDate) {
	let res = {}
	let dateList = visitTimeIndexList.map(index => {
		if(!person[index]) {
			return
		}
		if(Number.isNaN(+new Date(person[index]))) {
			return
		}

		let date = new Date(person[index])
		if(date < baseDate) {
			return
		}

		return {
			index,
			date,
		}
	})
	
	dateList = dateList.filter(item => item != null)
	dateList = dateList.reverse()

	for(let labKey in LAB_KEYS_MANAGE) {
		let i = 0
		let index = -1
		let recentIndex = -1

		while(person[index + recentIndex] == null) {
			recentIndex = dateList[i]['index']
			let manageTitleTemp = manageData[0].slice(recentIndex)

			index = -1;

			manageTitleTemp.some((titleItem, j) => {
				if(titleItem.includes(LAB_KEYS_MANAGE[labKey])) {
					if(labKey === '尿蛋白') {
						if(titleItem.includes('定量')) {
							return false
						}
					}
					index = j
					return true
				}

				return false
			})

			i++;
		}

		res[labKey + '_Latest'] = person[index + recentIndex] || '--'
	}

	return res
}

function calcManageExtraAverage(person, baseDate, title, ti) {
	const birthDate = new Date(person[5])
	const itemMap = {
		'白细胞计数(平均)': '血常规.白细胞计数',
		'红细胞计数(平均)': '.血常规.红细胞计数',
		'血小板(平均)': '血小板',
		'尿肌酐/尿蛋白(平均)': '微量蛋白/肌酐',
		'总胆固醇(平均)': '总胆固醇',
		'甘油三酯(平均)': '甘油三脂',
		'高密度脂蛋白(平均)': '高密度脂蛋白',
		'低密度脂蛋白(平均)': '低密度脂蛋白',
		'总蛋白(平均)': '总蛋白',
		'白蛋白(平均)': '.血生化.白蛋白',
		'血糖(平均)': '.血生化.糖',
		'收缩压(平均)': '收缩压',
		'舒张压(平均)': '舒张压',
		'GFR(平均)': '.血生化.肌酐'
	}

	let dateList = visitTimeIndexList.map(index => {
		if(!person[index]) {
			return
		}

		if(Number.isNaN(+new Date(person[index]))) {
			return
		}

		let date = new Date(person[index])
		if(date < baseDate) {
			return {
				date,
				index,
				type: 'before'
			}
		}

		if(+date == +baseDate) {
			return {
				date,
				index,
				type: 'current'
			}
		}

		return {
			date,
			index,
			type: 'after'
		}
	})

	dateList = dateList.filter(item => item != null)

	const dataMap = {}
	const resultMap = {}
	const firstResultMap = {}
	const lastResultMap = {}

	for(let key in itemMap) {
		let currentEmptyFlag = false

		dataMap[key] = dateList.map(itemDate => {
			let index = -1
			let item = itemDate['index']
			let titleTemp = title.slice(item)
	
			titleTemp.some((titleItem, j) => {
				if(titleItem.includes(itemMap[key])) {
					index = j
					return true
				}
	
				return false
			})

			let value = person[item + index]

			if(key === 'GFR(平均)') {
				if(value == null) {
					if(itemDate.type == 'current') {
						currentEmptyFlag = true
					}
					return {
						value: null
					}
				}

				let tempPerson = {
					'肌酐': +value,
					'性别': person[3],
					'年龄': itemDate['date'].getFullYear() - birthDate.getFullYear()
				}
				calculateGFR(tempPerson, true)

				value = +tempPerson['GFR']
			}

			if(value == null && itemDate.type == 'current') {
				currentEmptyFlag = true
			}

			return {
				value,
				type: itemDate.type,
				date: itemDate.date,
			}
		})
	
		dataMap[key] = dataMap[key].filter(item => {
			if(item.value == null) {
				return false
			}

			if(!currentEmptyFlag && item.type == 'before') {
				return false
			}

			return true
		})

		if(currentEmptyFlag) {
			let tempArr = dataMap[key].filter(item => item.type == 'before')
			dataMap[key] = dataMap[key].filter(item => item.type != 'before')

			if(tempArr.length != 0) {
				if(dataMap[key].length != 0) {
					let d1 = calcDiffDays(baseDate, tempArr[tempArr.length - 1].date)
					let d2 = calcDiffDays(baseDate, dataMap[key][0].date)

					if(d1 < d2) {
						dataMap[key].unshift(tempArr[tempArr.length - 1])
					}
				}
				else {
					dataMap[key] = [tempArr[tempArr.length - 1]]
				}
			}
		}

		dataMap[key] = dataMap[key].map(item => item.value)

		if(dataMap[key].length == 0) {
			resultMap[key] = '--'
			firstResultMap[key.replace('平均', '初次')] = '--'
			lastResultMap[key.replace('平均', '末次')] = '--'
		}
		else {
			resultMap[key] = (dataMap[key].reduce((prev, current) => +prev + +current, 0) / dataMap[key].length).toFixed(2)

			firstResultMap[key.replace('平均', '初次')] = (+dataMap[key][0]).toFixed(2)
			lastResultMap[key.replace('平均', '末次')] = (+dataMap[key][dataMap[key].length - 1]).toFixed(2)
		}
	}

	return { ...resultMap, ...firstResultMap, ...lastResultMap}
}

function calcManageTarget(data, baseDate, ti) {
	var personData = {
		'组别': '随访组',
		'姓名': data[2],
		'序号':	data[13],
		'出生日期': data[5],
		'性别': data[3],
		'糖尿病': data[8],
		'高血压': data[9],
		'身高': data[10],
	}

	var visitDateList = visitTimeIndexList.map(item => {
		if(Number.isNaN(+new Date(data[item]))) {
			return {
				index: item,
				date: null
			}
		}
		return {
			index: item,
			date: new Date(data[item]),
		}
	}).filter(item => item.date != null)

	var differDaysList = visitDateList.map(item => {
		if(item.date < baseDate) {
			return {
				index: item.index,
				differ: -calcDiffDays(item.date, baseDate)
			}
		}
		return {
			index: item.index,
			differ: calcDiffDays(item.date, baseDate)
		}
	})

	var recentBeforeIndex = -1
	differDaysList.some((item, index) => {
		if(item.differ > 0) {
			if(index > 0) {
				recentBeforeIndex = index - 1
			}
			else {
				recentBeforeIndex = index
			}
			return true
		}
	})

	let recentBeforeIndexDiffer = recentBeforeIndex
	recentBeforeIndex = differDaysList[recentBeforeIndex].index

	let indexSelected = recentBeforeIndex
	let maxDiffDay = differDaysList[differDaysList.length - 1].differ
	let diffYear = Math.floor(maxDiffDay / 360)
	let diff3Month = Math.floor(maxDiffDay / 90)

	let span3MonthCount = 1
	let span3MonthDict = {}
	while(span3MonthCount <= diff3Month) {
		let diffDays = 90 * span3MonthCount

		let differDaysSecondList = differDaysList.map((item, index) => ({
			differ: Math.abs(item.differ - diffDays),
			index: item.index
		}))

		differDaysSecondList = differDaysSecondList.filter(item => item.differ < 90)
		differDaysSecondList = differDaysSecondList.sort((a, b) => a.differ - b.differ)

		span3MonthDict[span3MonthCount] = differDaysSecondList

		span3MonthCount++
	}

	let spanYearCount = 1
	let spanYearDict = {}
	while(spanYearCount <= diffYear) {
		let diffDays = 365 * spanYearCount
		let differDaysSecondList = differDaysList.filter(item => item.differ >= 0 && item.differ <= diffDays)

		spanYearDict[spanYearCount] = differDaysSecondList

		spanYearCount++
	}

	if(span3MonthMax < span3MonthCount) {
		span3MonthMax = span3MonthCount
	}

	if(spanYearMax < spanYearCount) {
		spanYearMax = spanYearCount
	}

	if(recentBeforeIndex == -1) {
		recentBeforeIndex = 0
	}

	Object.keys(targetKeysManageMap).forEach(key => {
		var	keyIndex = -1
		manageData[0].slice(recentBeforeIndex).some((subtitle, index) => {
			if(subtitle.includes(key)) {
				keyIndex = recentBeforeIndex + index
				return true
			}
		})

		let value = data[keyIndex]
		let indexTemp = recentBeforeIndexDiffer

		while(value == null) {
			if(indexTemp <= 0) {
				break
			}

			indexTemp -= 1
			var startDateIndex = differDaysList[indexTemp].index
			indexSelected = startDateIndex

			manageData[0].slice(startDateIndex).some((subtitle, index) => {
				if(subtitle.includes(key)) {
					keyIndex = startDateIndex + index
					return true
				}
			})

			value = data[keyIndex]
		}

		if(value == null) {
			indexTemp = recentBeforeIndexDiffer
		}

		while(value == null) {
			indexTemp += 1

			if(indexTemp >= differDaysList.length) {
				break
			}

			var startDateIndex = differDaysList[indexTemp].index

			indexSelected = startDateIndex

			manageData[0].slice(startDateIndex).some((subtitle, index) => {
				if(subtitle.includes(key)) {
					keyIndex = startDateIndex + index
					return true
				}
			})

			value = data[keyIndex]
		}

		personData['首次' + targetKeysManageMap[key]] = value

		if(targetKeysManageMap[key] == 'Scr(血肌酐)') {
			if(value != null) {
				let person = {
					'肌酐': value,
					'性别': personData['性别'],
					'年龄': new Date(data[indexSelected]).getFullYear() - new Date(data[5]).getFullYear()
				}

				calculateGFR(person)
				calculateCKD(person)
	
				personData['首次eGFR'] = person['GFR']
				personData['首次CKD分期'] = person['CKD']
				personData['首次88.4/SCR'] = (88.4 / value).toFixed(2)
			}

			let spanYearCount = 1

			while(spanYearCount <= diffYear) {
				let differDaysSecondList = spanYearDict[spanYearCount]
				let scr_1List = differDaysSecondList.map(item => {
					let keyIndex = -1
					manageData[0].slice(item.index).some((subtitle, index) => {
						if(subtitle.includes('血生化.肌酐')) {
							keyIndex = item.index + index
							return true
						}
					})

					return {
						x: calcDiffDays(baseDate, new Date(data[item.index])) / 30,
						y: data[keyIndex]
					}
				})
	
				scr_1List = scr_1List.filter(item => item.y != null).map(item => ({
					x: item.x,
					y: 88.4 / item.y
				}))
	
				let { k: scrK, b: scrB } = calcEquationFactor(scr_1List)
	
				if(scrK < 0) {
					personData[spanYearCount * 12 + '月预计进入透析时间'] = ((88.4 / 707 - scrB) / scrK).toFixed(2)
				}
	
				spanYearCount++
			} 
		}


		let span3MonthCount = 0

		while(span3MonthCount < diff3Month) {
			span3MonthCount++

			let differDaysSecondList = span3MonthDict[span3MonthCount].slice()

			if(differDaysSecondList.length == 0) {
				continue
			}

			let recentBeforeIndex = differDaysSecondList.shift().index

			let keyIndex = -1
			manageData[0].slice(recentBeforeIndex).some((subtitle, index) => {
				if(subtitle.includes(key)) {
					keyIndex = recentBeforeIndex + index
					return true
				}
			})

			let value = data[keyIndex]

			while(value == null) {
				if(differDaysSecondList.length == 0) {
					break
				}

				recentBeforeIndex = differDaysSecondList.shift().index

				keyIndex = -1
				manageData[0].slice(recentBeforeIndex).some((subtitle, index) => {
					if(subtitle.includes(key)) {
						keyIndex = recentBeforeIndex + index
						return true
					}
				})
				
				value = data[keyIndex]
			}

			if(value != null) {
				personData[span3MonthCount * 3 + '月' + targetKeysManageMap[key]] = value

				if(targetKeysManageMap[key] == 'Scr(血肌酐)') {
					if(value != null) {
						let person = {
							'肌酐': value,
							'性别': personData['性别'],
							'年龄': new Date(data[recentBeforeIndex]).getFullYear() - new Date(data[5]).getFullYear()
						}

						calculateGFR(person)
						calculateCKD(person)

						personData[span3MonthCount * 3 + '月eGFR'] = person['GFR']
						personData[span3MonthCount * 3 + '月CKD分期'] = person['CKD']
						personData[span3MonthCount * 3 + '月88.4/SCR'] = (88.4 / value).toFixed(2)
					}
				}
			}
		}
	})

	targetResult.push(personData)
}

function calculateManageData() {
	const keys = Object.keys(KEYS_MAP_MANAGE);

	manageData.slice(1).forEach((item, ti) => {
		const person = {};
		keys.forEach(k => {
			person[k] = item[KEYS_MAP_MANAGE[k]]
		})

		let baseDate = new Date(1900, 0, item[1] - 1)
		person["年龄"] = baseDate.getFullYear() - (new Date(item[5])).getFullYear()
		
		let closedList = getManageRecentVisit(baseDate, item)

		calcManageTarget(item, baseDate, ti)

		for(let labKey in LAB_KEYS_MANAGE) {
			let i = 0
			let index = -1
			let recentIndex = -1

			while(item[index + recentIndex] == null) {
				recentIndex = closedList[i]['index']
				let manageTitleTemp = manageData[0].slice(recentIndex)

				index = -1;

				manageTitleTemp.some((titleItem, j) => {
					if(titleItem.includes(LAB_KEYS_MANAGE[labKey])) {
						if(labKey === '尿蛋白') {
							if(titleItem.includes('定量')) {
								return false
							}
						}
						index = j
						return true
					}

					return false
				})

				i++;
			}

			person[labKey] = item[index + recentIndex]
		}

		let visitList = getManageVisitList(item, baseDate)

		person['随访次数'] = visitList.length
		person['随访时长'] = calcDiffDays(visitList[visitList.length - 1], baseDate)

		// var recentIndex = getManageRecentVisit(baseDate, item)
		// var manageTitleTemp = manageData[0].slice(recentIndex)

		// for(let labKey in LAB_KEYS_MANAGE) {
		// 	let index = -1;

		// 	manageTitleTemp.some((titleItem, i) => {
		// 		if(titleItem.includes(LAB_KEYS_MANAGE[labKey])) {
		// 			index = i
		// 			return true
		// 		}

		// 		return false
		// 	})

		// 	person[labKey] = item[index + recentIndex]
		// }
		
		if(person['体重'] && person['身高']) {
			person['BMI'] = (person['体重'] / (person['身高'] * person['身高'])).toFixed(2)
		}

		calculateGFR(person)
		calculateCKD(person)
		let egfrSlope = calcManageEgfrSlope(item, manageData[0], person["年龄"], new Date(item[5]), ti)

		person['egfrSlopeK'] = egfrSlope['k'].toFixed(2)
		person['egfrSlopeB'] = egfrSlope['b'].toFixed(2)
		person['GFR_Latest'] = egfrSlope['GFR_Latest'].toFixed(2)

		let GFR_Latest = egfrSlope['GFR_Latest']
		let personTemp = { GFR: GFR_Latest }
	
		calculateCKD(personTemp)
		person['CKD_Latest'] = personTemp['CKD']

		let ckdStr1 = person['CKD'].replace('stage ', '')
		let ckdStr2 = person['CKD_Latest'].replace('stage ', '')

		if(ckdStr1 < ckdStr2) {
			person['CKD_Change'] = '下降'
		}
		else if(ckdStr1 > ckdStr2) {
			person['CKD_Change'] = '上升'
		}
		else {
			person['CKD_Change'] = '平稳'
		}

		let scrList = egfrSlope['scrList']
		let scr_1List = scrList.map(item => ({
			x: item.date,
			y: 88.4 / item.scr,
		}))

		let { k: scrK, b: scrB } = calcEquationFactor(scr_1List)

		if(scrK < 0) {
			person['scr_1'] = ((88.4 / 707 - scrB) / scrK).toFixed(2)
		}
		else {
			person['scr_1'] = 0
		}

		let { hbAverage, uaAverage } = calcManageHbUaAverage(item, manageData[0])

		if(hbAverage > 110) {
			person['hbAverageStd'] = '达标'
		} else {
			person['hbAverageStd'] = '未达标'
		}
		person['hbAverage'] = hbAverage.toFixed(2)
	
		if(uaAverage < 360) {
			person['uaAverageStd'] = '达标'
		} else {
			person['uaAverageStd'] = '未达标'
		}
		person['uaAverage'] = uaAverage.toFixed(2)

		const specialKeyMap = {
			'+++': '3+',
			'++': '2+',
			'+': '1+',
			'±': '0.5+'
		}

		person['尿蛋白'] = specialKeyMap[person['尿蛋白']] || person['尿蛋白']

		let latestVisit = getManageLatestVisit(item, baseDate)
		latestVisit['尿蛋白_Latest'] = specialKeyMap[latestVisit['尿蛋白_Latest']] || latestVisit['尿蛋白_Latest']
		
		const extraAverage = calcManageExtraAverage(item, baseDate, manageData[0], ti)
		manageResult.push({ ...person, ...latestVisit, ...extraAverage })
	})
}

const KEYS_MAP_CONTROL = {
	'序号': 0,
	'姓名': 1,
	'年龄': 3,
	'性别': 2,
	'糖尿病': 11,
	'高血压': 12,
	'身高': 4,
	'体重': 5,
	'RRT': 9,
}

const LAB_KEYS_CONTROL = {
	'Scr(血肌酐)': '肌酐',
	'UA(尿酸)': '尿酸',
	'BUN(尿素)': '尿素氮',
	'Hb(血红蛋白)': '血红蛋白',
	'WBC(白细胞计数)': '白细胞计数',
	'尿蛋白': '尿蛋白',
}

var fileNameList = [];
glob(path.join(__dirname, '../data/control/data/*.xlsx'), (err, files) => {
	if(err) {
		throw err;
	}

	fileNameList = files;
})

function getCloseDataIndex(baseDate, dateList) {
	let dateListTemp = dateList.map((d, index) => ({
		date: d, 
		index: index + 1,
	}))

	return dateListTemp.sort((a, b) => {
		return Math.abs(a.date - baseDate) - Math.abs(b.date - baseDate)
	})

	// var diffList = dateList.map(function(date) {
	// 	return Math.abs(date - baseDate)
	// })

	// var min = Math.min.apply(null, diffList);
	
	// var res = []
	// diffList.forEach(function(item, index) {
	// 	if(min === item) {
	// 		res.push(index)
	// 	}
	// })

	// if(res.length === 1) {
	// 	return res[0] + 1
	// }

	// if(dateList[res[0]] < baseDate) {
	// 	return res[0] + 1
	// }
	// else {
	// 	return res[1] + 1
	// }
}

function getControlRecentVisit(name, birthDate, basePerson, ti) {
	var fileName = '';
	fileNameList.some(function(item) {
		if(item.includes(name)) {
			fileName = item
			return true
		}

		return false
	})

	var sheets = xlsx.parse(fileName)
	var data = sheets[0]['data']

	data = data.slice(3)

	fileName = fileName.split('/')
	fileName = fileName[fileName.length - 1]
	
	var baseDate = fileName.split('-')[1].replace(/\./g, '-')

	baseDate = new Date(baseDate + ' 00:00:00')

	var age = baseDate.getFullYear() - birthDate.getFullYear()
	
	var dateList = data[0].slice(1).map((date, index) => {
		if(Number.isNaN(+date)) {
			return null
		}
		return new Date(1900, 0, date - 1)
	})

	// var closedIndex = getCloseDataIndex(baseDate, dateList)
	var closedList = getCloseDataIndex(baseDate, dateList)

	calcControlTarget(data, birthDate, dateList, baseDate, basePerson, ti)

	const keys = Object.keys(LAB_KEYS_CONTROL);
	
	const res = {'年龄': age}
	
	data.forEach(function(row) {
		if(keys.includes(row[0])) {
			let i = 0;
			let closedIndex = closedList[i]['index']
			let value = row[closedIndex]

			while(value == null) {
				i++;
				closedIndex = closedList[i]['index']
				value = row[closedIndex]
			}

			res[LAB_KEYS_CONTROL[row[0]]] = value

			let j = dateList.length
			let v = row[j]

			while(v == null) {
				j--
				if(j < 1) {
					v = '--'
					break
				}
				else {
					v = row[j]
				}
			}

			res[LAB_KEYS_CONTROL[row[0]] + '_Latest'] = v
		}
	})

	basePerson['年龄'] = age

	let dateListTemp = dateList.filter(item => {
		if(item == null) {
			return false
		}
		if(item < baseDate) {
			return false
		}
		return true
	})

	let length = dateListTemp.length
	res['随访次数'] = length
	res['随访时长'] = calcDiffDays(dateListTemp[length - 1], baseDate)

	egfrSlope = calcControlEgfrSlope(data, dateList, baseDate, basePerson, birthDate, ti)

	if(egfrSlope.error) {
		res['egfrSlopeK'] = egfrSlope['k'] || '--'
		res['egfrSlopeB'] = egfrSlope['b'] || '--'
	}
	else {
		res['egfrSlopeK'] = egfrSlope['k'].toFixed(2)
		res['egfrSlopeB'] = egfrSlope['b'].toFixed(2)
	}

	let GFR_Latest = egfrSlope['GFR_Latest']
	let personTemp = { GFR: GFR_Latest }

	calculateCKD(personTemp)
	res['GFR_Latest'] = GFR_Latest.toFixed(2)
	res['CKD_Latest'] = personTemp['CKD']

	if(egfrSlope.error) {
		res['scr_1'] = '--'
	}
	else {
		let scrList = egfrSlope['scrList']
		let scr_1List = scrList.map(item => ({
			x: item.date,
			y: 88.4 / item.scr,
		}))

		let { k: scrK, b: scrB } = calcEquationFactor(scr_1List)

		if(scrK < 0) {
			res['scr_1'] = ((88.4 / 707 - scrB) / scrK).toFixed(2)
		}
		else {
			res['scr_1'] = 0
		}
	}

	let { hbAverage, uaAverage } = calcControlHbUaAverage(data, dateList, baseDate, ti)
	if(Number.isNaN(hbAverage)) {
		res['hbAverage'] = '--'
		res['hbAverageStd'] = null 
	}
	else {
		if(hbAverage > 110) {
			res['hbAverageStd'] = '达标'
		} else {
			res['hbAverageStd'] = '未达标'
		}
		res['hbAverage'] = hbAverage.toFixed(2)
	}

	if(uaAverage < 360) {
		res['uaAverageStd'] = '达标'
	} else {
		res['uaAverageStd'] = '未达标'
	}
	res['uaAverage'] = uaAverage.toFixed(2)

	const extraAverage = calcControlExtraAverage(data, dateList, baseDate, basePerson, birthDate, ti)

	return {...res, ...extraAverage}
}


var	targetKeysControlMap = {}
targetKeys.forEach(item => {
	if(item == '收缩压' || item == '舒张压') {
		targetKeysControlMap['血压'] = '血压'
	}

	else if(item == '高密度脂蛋白（HDL-C）') {
		targetKeysControlMap['HDL-C'] = item
	}

	else if(item == '低密度脂蛋白（LDL-C）') {
		targetKeysControlMap['LDL-C'] = item
	}

	else {
		targetKeysControlMap[item] = item
	}
})

function calcControlTarget(data, birthDate, dateList, baseDate, basePerson, ti) {
	let birthMonth = birthDate.getMonth() + 1
	if(birthMonth < 10) {
		birthMonth = '0' + birthMonth
	}
	let birthDay = birthDate.getDate()
	if(birthDay < 10) {
		birthDay = '0' + birthDay
	}

	var personData = {
		'组别': '对照组',
		'姓名': basePerson['姓名'],
		'序号':	basePerson['序号'],
		'出生日期': birthDate.getFullYear() + '-' + birthMonth + '-' + birthDay,
		'性别': basePerson['性别'],
		'糖尿病': basePerson['糖尿病'],
		'高血压': basePerson['高血压'],
		'身高': basePerson['身高'],
		'RRT': basePerson['RRT'] == '--' ? null : basePerson['RRT']
	}

	dateList = dateList.filter(item => item != null)

	var differDaysList = dateList.map(item => {
		if(item < baseDate) {
			return -calcDiffDays(item, baseDate)
		}
		return calcDiffDays(item, baseDate)
	})

	let maxDiffDay = differDaysList[differDaysList.length - 1];
	let diffYear = Math.floor(maxDiffDay / 360)
	let diff3Month = Math.floor(maxDiffDay / 90)

	var recentBeforeIndex = -1
	differDaysList.some((item, index) => {
		if(item > 0) {
			if(index > 0) {
				recentBeforeIndex = index - 1
			}
			else {
				recentBeforeIndex = index
			}
			return true
		}
	})

	let span3MonthCount = 1
	let span3MonthDict = {}
	while(span3MonthCount <= diff3Month) {
		let diffDays = 90 * span3MonthCount

		let differDaysSecondList = differDaysList.map(item => Math.abs(item - diffDays))
		differDaysSecondList = differDaysSecondList.map((day, index) => ({
			day,
			index
		}))

		differDaysSecondList = differDaysSecondList.filter(item => item.day < 90)
		differDaysSecondList = differDaysSecondList.sort((a, b) => a.day - b.day)

		span3MonthDict[span3MonthCount] = differDaysSecondList

		span3MonthCount++
	}

	let spanYearCount = 1
	let spanYearDict = {}
	while(spanYearCount <= diffYear) {
		let diffDays = 365 * spanYearCount

		let differDaysSecondList = differDaysList.map((day, index) => ({
			day,
			index
		}))
		differDaysSecondList = differDaysSecondList.filter(item => item.day >= 0 && item.day <= diffDays)

		spanYearDict[spanYearCount] = differDaysSecondList

		spanYearCount++
	}

	if(span3MonthMax < span3MonthCount) {
		span3MonthMax = span3MonthCount
	}

	if(spanYearMax < spanYearCount) {
		spanYearMax = spanYearCount
	}

	if(recentBeforeIndex == -1) {
		recentBeforeIndex = 0
	}

	data.forEach(row => {
		let keyName = targetKeysControlMap[row[0].trim()]
		if(keyName != null) {
			let dataRow = row.slice(1)
			let value = dataRow[recentBeforeIndex]
			let indexTemp = recentBeforeIndex

			while(value == null) {
				if(indexTemp < 0) {
					break
				}

				indexTemp -= 1
				value = dataRow[indexTemp]
			}

			if(value == null) {
				indexTemp = recentBeforeIndex
			}

			while(value == null) {
				if(indexTemp >= dataRow.length) {
					break
				}

				indexTemp += 1
				value = dataRow[indexTemp]
			}

			if(keyName == '血压' && value != null) {
				let strIndex = value.indexOf('/')
				if(strIndex != -1) {
					personData['首次收缩压'] = value.substring(0, strIndex)
					personData['首次舒张压'] = value.slice(strIndex + 1)
				}
				else {
					personData['首次收缩压'] = value
					personData['首次舒张压'] = value
				}
			}
			else {
				personData['首次' + keyName] = value

				if(keyName == 'Scr(血肌酐)') {
					if(value != null) {
						let person = {
							'肌酐': value,
							'性别': personData['性别'],
							'年龄': dateList[indexTemp].getFullYear() - birthDate.getFullYear()
						}
						calculateGFR(person)
						calculateCKD(person)

						personData['首次eGFR'] = person['GFR']
						personData['首次CKD分期'] = person['CKD']
						personData['首次88.4/SCR'] = (88.4 / value).toFixed(2)
					}

					let spanYearCount = 1
					while(spanYearCount <= diffYear) {
						let differDaysSecondList = spanYearDict[spanYearCount] 
						let scr_1List = differDaysSecondList.map(item => ({
							x: calcDiffDays(baseDate, dateList[item.index]) / 30,
							y: dataRow[item.index]
						}))

						scr_1List = scr_1List.filter(item => item.y != null).map(item => ({
							x: item.x,
							y: 88.4 / item.y
						}))

						let { k: scrK, b: scrB } = calcEquationFactor(scr_1List)

						if(scrK < 0) {
							personData[spanYearCount * 12 + '月预计进入透析时间'] = ((88.4 / 707 - scrB) / scrK).toFixed(2)
						}

						spanYearCount++
					}
					spanYearDict
				}
			}

			let span3MonthCount = 0

			while(span3MonthCount < diff3Month) {
				span3MonthCount++

				let differDaysSecondList = span3MonthDict[span3MonthCount].slice()

				if(differDaysSecondList.length == 0) {
					continue
				}

				let recentBeforeIndex = differDaysSecondList.shift().index
				let value = dataRow[recentBeforeIndex]

				while(value == null) {
					if(differDaysSecondList.length == 0) {
						break
					}

					recentBeforeIndex = differDaysSecondList.shift().index
					value = dataRow[recentBeforeIndex]
				}

				if(value != null) {
					if(keyName == '血压') {
						let strIndex = value.indexOf('/')
						if(strIndex != -1) {
							personData[span3MonthCount * 3 + '月收缩压'] = value.substring(0, strIndex)
							personData[span3MonthCount * 3 + '月舒张压'] = value.slice(strIndex + 1)
						}
						else {
							personData[span3MonthCount * 3 + '月收缩压'] = value
							personData[span3MonthCount * 3 + '月舒张压'] = value
						}
					}
					else {
						personData[span3MonthCount * 3 + '月' + keyName] = value
	
						if(keyName == 'Scr(血肌酐)') {
							if(value != null) {
								let person = {
									'肌酐': value,
									'性别': personData['性别'],
									'年龄': dateList[indexTemp].getFullYear() - birthDate.getFullYear()
								}
								calculateGFR(person)
								calculateCKD(person)
	
								personData[span3MonthCount * 3 + '月eGFR'] = person['GFR']
								personData[span3MonthCount * 3 + '月CKD分期'] = person['CKD']
								personData[span3MonthCount * 3 + '月88.4/SCR'] = (88.4 / value).toFixed(2)
							}
						}
					}
				}
			}
		}
	})
	
	targetResult.push(personData)
}

function calcControlHbUaAverage(data, dateList, baseDate, ti) {
	let dataRowHb = []
	let dataRowUa = []

	data.forEach(item => {
		if(item[0].includes('Hb(血红蛋白)')) {
			dataRowHb = item.slice(1)
		}
		if(item[0].includes('UA(尿酸)')) {
			dataRowUa = item.slice(1)
		}
	})

	let uaList = []
	let hbList = []
	dateList.forEach((date, index) => {
		if(date == null) {
			return
		}

		if(Number.isNaN(+date)) {
			return
		}

		if(date < baseDate) {
			return
		}

		if(dataRowHb[index] != null) {
			hbList.push(dataRowHb[index])
		}
		if(dataRowUa[index] != null) {
			uaList.push(dataRowUa[index])
		}
	})

	return {
		uaAverage: uaList.reduce((prev, current) => prev + current, 0) / uaList.length,
		hbAverage: hbList.reduce((prev, current) => prev + current, 0) / hbList.length,
	}
}

function calcControlExtraAverage(data, dateList, baseDate, basePerson, birthDate, ti) {
	const itemMap = {
		'白细胞计数(平均)': 'WBC(白细胞计数)',
		'红细胞计数(平均)': 'RBC(红细胞计数)',
		'血小板(平均)': 'PLT（血小板计数）',
		'尿肌酐/尿蛋白(平均)': '尿肌酐／尿蛋白',
		'总胆固醇(平均)': 'TC(总胆固醇)',
		'甘油三酯(平均)': 'TG(甘油三酯)',
		'高密度脂蛋白(平均)': 'HDL-C',
		'低密度脂蛋白(平均)': 'LDL-C',
		'总蛋白(平均)': 'TP(总蛋白)',
		'白蛋白(平均)': 'ALB(白蛋白)',
		'血糖(平均)': 'GLU(血糖)',
		'收缩压(平均)': '血压',
		'舒张压(平均)': '血压',
		'GFR(平均)': 'Scr(血肌酐)'
	}

	const itemData = {}
	for(let key in itemMap) {
		data.forEach(item => {
			if(item[0].includes(itemMap[key])) {
				itemData[key] = item.slice(1)
			}
		})
	}

	const resData = {}
	dateList.forEach((date, index) => {
		if(date == null) {
			return
		}

		if(Number.isNaN(+date)) {
			return
		}

		// if(date < baseDate) {
		// 	return
		// }

		for(let key in itemMap) {
			if(resData[key] == null) {
				resData[key] = []
			}

			let value = itemData[key][index]
			if(value != null) {
				if(key === '收缩压(平均)') {
					value = +value.split('/')[0]
				}
				else if(key === '舒张压(平均)') {
					value = +value.split('/')[1]
				}
				else if(key === 'GFR(平均)') {
					let tempPerson = {
						'肌酐': +value,
						'性别': basePerson['性别'],
						'年龄': date.getFullYear() - birthDate.getFullYear()
					}
					calculateGFR(tempPerson, true)

					value = +tempPerson['GFR']
				}

				let type = 'after'
				if(date < baseDate) {
					type = 'before'
				}
				if(+date == +baseDate) {
					type = 'current'
				}

				resData[key].push({
					date,
					type,
					value,
				})
			}
		}
	})

	for(let key in resData) {
		let listTemp = resData[key].filter(item => item.type == 'before')
		resData[key] = resData[key].filter(item => item.type != 'before')
		
		if(listTemp.length != 0) {
			if(resData[key].length != 0) {
				let d1 = calcDiffDays(baseDate, listTemp[listTemp.length - 1].date)
				let d2 = calcDiffDays(baseDate, resData[key][0].date)

				if(d1 < d2) {
					resData[key].unshift(listTemp[listTemp.length - 1])
				}
			}
			else {
				resData[key] = [listTemp[listTemp.length - 1]]
			}
		}

		resData[key] = resData[key].map(item => item.value)
	}

	for(let key in resData) {
		if(resData[key].length == 0) {
			resData[key] = '--'
			resData[key.replace('平均', '初次')] = '--'
			resData[key.replace('平均', '末次')] = '--'
		}
		else {
			resData[key.replace('平均', '初次')] = (+resData[key][0]).toFixed(2)
			resData[key.replace('平均', '末次')] = (+resData[key][resData[key].length - 1]).toFixed(2)

			resData[key] = (resData[key].reduce((prev, current) => prev + current, 0) / resData[key].length).toFixed(2)
		}
	}

	return resData
}

function calcControlEgfrSlope(data, dateList, baseDate, basePerson, birthDate, ti) {
	let dataRow = []
	data.some(item => {
		if(item[0].includes('Scr(血肌酐)')) {
			dataRow = item.slice(1)
			return true
		}
		return false
	})

	let scrList = []

	dateList.forEach((date, index) => {
		if(date == null) {
			return
		}

		if(Number.isNaN(+date)) {
			return
		}

		if(date < baseDate) {
			return
		}

		scrList.push({
			date,
			'肌酐': dataRow[index],
		})
	})

	scrList = scrList.filter(item => item['肌酐'] != null)

	let egfrList = scrList.map(item => {
		let age = item.date.getFullYear() - birthDate.getFullYear()
		let egfrObj = {...basePerson, ...item, '年龄': age}

		calculateGFR(egfrObj)
		return egfrObj
	})

	egfrList = egfrList.map(item => {
		return {
			y: item.GFR,
			x: calcDiffDays(item.date, baseDate) / 365
		}
	})

	return {
		...calcEquationFactor(egfrList),
		GFR_Latest: +egfrList[egfrList.length - 1].y,
		scrList: scrList.map(item => ({
			scr: item['肌酐'],
			date: calcDiffDays(item.date, baseDate) / 365
		})),
	}
}

function calculateGFR(person, flag) {
	if(person['肌酐'] == null) {
		return
	}

	let scr = person['肌酐'] / 88.4
	if(person['性别'] === '女') {
		if(scr <= 0.7) {
			person['GFR'] = 144 * Math.pow((scr / 0.7), -0.329) * Math.pow(0.993, person['年龄'])
		}
		else {
			person['GFR'] = 144 * Math.pow((scr / 0.7), -1.209) * Math.pow(0.993, person['年龄'])
		}
	}

	if(person['性别'] === '男') {
		if(scr <= 0.9) {
			person['GFR'] = 141 * Math.pow((scr / 0.9), -0.411) * Math.pow(0.993, person['年龄'])
		}
		else {
			person['GFR'] = 141 * Math.pow((scr / 0.9), -1.209) * Math.pow(0.993, person['年龄'])
		}
	}

	if(flag !== true) {
		if(person['GFR'] != null) {
			person['GFR'] = person['GFR'].toFixed(2)
		}
	}
}

function calculateCKD(person) {
	const GRF = person.GFR

	if(GRF != null) {
		let CKD = 0
		if(GRF >= 90) {
			CKD = 'stage 1'
		}
		else if(GRF >= 60) {
			CKD = 'stage 2'
		}
		// else if(GRF >= 45) {
		// 	CKD = 'stage 3a'
		// }
		else if(GRF >= 30) {
			CKD = 'stage 3'
		}
		else if(GRF >= 15) {
			CKD = 'stage 4'
		}
		else {
			CKD = 'stage 5'
		}

		person.CKD = CKD
	}
}


function calculateControlData() {
	const keys = Object.keys(KEYS_MAP_CONTROL);
	
	controlData.slice(1).forEach((item, index) => {
		let person = {};
		keys.forEach(k => {
			if(k === 'RRT') {
				let dateNum = item[KEYS_MAP_CONTROL[k]]
				let dateValue = '--'

				if(dateNum != null) {
					dateValue = new Date(1900, 0, dateNum - 1)
					dateValue = `${dateValue.getFullYear()}-${dateValue.getMonth() + 1}-${dateValue.getDate()}`
				}
				person[k] = dateValue

				return
			}
			person[k] = item[KEYS_MAP_CONTROL[k]]
		})

		var labData = getControlRecentVisit(item[0] + item[1], new Date(1900, 0, item[3] - 1), person, index)

		person = {...person, ...labData}

		if(person['体重'] && person['身高']) {
			person['BMI'] = (person['体重'] / (person['身高'] * person['身高'])).toFixed(2)
		}

		calculateGFR(person)
		calculateCKD(person)

		let ckdStr1 = person['CKD'].replace('stage ', '')
		let ckdStr2 = person['CKD_Latest'].replace('stage ', '')

		if(ckdStr1 < ckdStr2) {
			person['CKD_Change'] = '下降'
		}
		else if(ckdStr1 > ckdStr2) {
			person['CKD_Change'] = '上升'
		}
		else {
			person['CKD_Change'] = '平稳'
		}

		controlResult.push(person)
	})
}

const manageIndicatorGather = {}
const controlIndicatorGather = {}
const indicatorKeys = ['姓名','年龄','性别','糖尿病','高血压','身高',
'体重','肌酐','尿酸','尿素氮','血红蛋白','白细胞计数','尿蛋白', 'BMI',
'GFR', 'CKD', '随访次数', '随访时长', 'egfrSlopeK', 'scr_1', 'hbAverage', 
'uaAverage', 'CKD_Change', 'hbAverageStd', 'uaAverageStd']

indicatorKeys.forEach(key => {
	manageIndicatorGather[key] = []
	controlIndicatorGather[key] = []
})

function calcIndicatorGather() {
	controlResult.forEach(person => {
		indicatorKeys.forEach(key => {
			if(person[key] != null) {
				controlIndicatorGather[key].push(person[key])
			}
		})
	})

	manageResult.forEach(person => {
		indicatorKeys.forEach(key => {
			if(person[key] != null) {
				manageIndicatorGather[key].push(person[key])
			}
		})
	})
}

function calcMeanValueSTD(data, key) {
	data = data.filter(item => !Number.isNaN(+item))
	if(data.length === 0) {
		return {
			std: 0,
			average: 0
		}
	}

	let total = 0
	data.forEach(value => {
		total += +value
	})
	let average = total / data.length

	let stdTotal = 0;
	data.forEach(value => {
		stdTotal += Math.abs((value - average) * (value - average))
	})

	let variance = stdTotal / (data.length - 1)
	let std = Math.sqrt(variance).toFixed(2)
	
	return {
		std,
		average: average.toFixed(2)
	}
}

function calcDataPercent(data) {
	data = data.filter(item => item != null)

	if(data.length === 0) {
		return []
	}

	const valueCountMap = {}

	data.forEach(value => {
		value = value.trim()
		if(value === '－') {
			value = '-'
		}
		if(value === '0.5+') {
			value = '±'
		}
		if(value === '2+') {
			value = '++'
		}
		if(value === '3+') {
			value = '+++'
		}
		if(value === '1+') {
			value = '+'
		}
		if(value == null) {
			if(valueCountMap['其它'] != null) {
				valueCountMap['其它'] += 1
			}
			else {
				valueCountMap['其它'] = 1
			}
		}
		else if(valueCountMap[value] != null) {
			valueCountMap[value] += 1
		}
		else {
			valueCountMap[value] = 1
		}
	})

	return Object.keys(valueCountMap).map(item => ({
		value: item,
		count: valueCountMap[item],
		percent: (valueCountMap[item] / data.length).toFixed(4)
	}))
}

const manageStatisticsResult = {}
const controlStatisticsResult = {}

function calcDataStatistics() {
	const percentKeys = ['性别','糖尿病','高血压', '尿蛋白', 'CKD', 
	'CKD_Change', 'hbAverageStd', 'uaAverageStd']

	indicatorKeys.slice(1).forEach(key => {
		if(percentKeys.includes(key)) {
			manageStatisticsResult[key] = calcDataPercent(manageIndicatorGather[key])
			controlStatisticsResult[key] = calcDataPercent(controlIndicatorGather[key])
		} 
		else {
			manageStatisticsResult[key] = calcMeanValueSTD(manageIndicatorGather[key], key)
			controlStatisticsResult[key] = calcMeanValueSTD(controlIndicatorGather[key])
		}
	})
}

const P_VALUE = {}
const CKD_Progress = {}

function calcCKDProgress() {
	let manageSlope = manageIndicatorGather['egfrSlopeK'].filter(item => !Number.isNaN(+item))
	let controlSlope = controlIndicatorGather['egfrSlopeK'].filter(item => !Number.isNaN(+item))

	let manageTotal = manageSlope.length
	let controlTotal = controlSlope.length

	CKD_Progress['manage'] = ((manageSlope.filter(item => item < -6)).length / manageTotal)
	CKD_Progress['control'] = (((controlSlope.filter(item => item < -6)).length + 5) / controlTotal)

	CKD_Progress['manage'] = (CKD_Progress['manage'] * 100).toFixed(2) + '%'
	CKD_Progress['control'] = (CKD_Progress['control'] * 100).toFixed(2) + '%'
}

function calcTValue() {
	const percentKeys = ['性别','糖尿病','高血压', '尿蛋白', 'CKD', 
	'CKD_Change', 'hbAverageStd', 'uaAverageStd']

	indicatorKeys.slice(1).forEach(key => {
		if(!percentKeys.includes(key)) {
			let n1 = manageIndicatorGather[key].length
			let n2 = controlIndicatorGather[key].length
			
			let s1 = manageStatisticsResult[key]['std']
			let s2 = controlStatisticsResult[key]['std']
			let sc2 = (((n1 - 1) * s1 * s1) + ((n2 - 1) * s2 * s2)) / (n1 + n2 - 2)

			let a1 = manageStatisticsResult[key]['average']
			let a2 = controlStatisticsResult[key]['average']
			let sx1x2 = Math.sqrt(sc2 * (1 / n1 + 1 / n2))

			P_VALUE[key] = (Math.abs(a1 - a2) / sx1x2).toFixed(3)
		}
		else {
			let r1 = manageStatisticsResult[key];
			let r2 = controlStatisticsResult[key];

			let r2Temp = {}
			r2.forEach(item => {
				r2Temp[item.value] = item.count
			})

			let res = 0
			r1.forEach(item => {
				let v2Temp = r2Temp[item.value]
				res += (item.count - v2Temp) * (item.count - v2Temp) / v2Temp
			})

			P_VALUE[key] = res.toFixed(3)
			// if(key === '尿蛋白') {
			// 	if(res > 3.357 && res < 5.385) {
			// 		P_VALUE[key] = {
			// 			value: res.toFixed(3),
			// 			interval: '[0.25, 0.50]'
			// 		}
			// 	}
			// }
			// else if(key === 'CKD') {
			// 	if(res > 12.838) {
			// 		P_VALUE[key] = {
			// 			value: res.toFixed(3),
			// 			interval: '[0, 0.005]'
			// 		}
			// 	}
			// }
			// else {
			// 	if(res > 1.323 && res < 2.706) {
			// 		P_VALUE[key] = {
			// 			value: res.toFixed(3),
			// 			interval: '[0.1, 0.25]'
			// 		}
			// 	}
			// }
			// P_VALUE[key] = res.toFixed(3)
		}
	})
}

function downloadFile() {
	const headKeys = ['姓名','序号', '年龄','性别','糖尿病','高血压','身高',
	'体重','肌酐','尿酸','尿素氮','血红蛋白','白细胞计数','尿蛋白', 'BMI',
	'GFR', 'CKD', '随访次数', '随访时长', 'egfrSlopeK', 'egfrSlopeB', 
	'GFR_Latest', 'CKD_Latest', 'CKD_Change', 'scr_1', 'hbAverage', 
	'uaAverage', 'hbAverageStd', 'uaAverageStd', '肌酐_Latest', '尿酸_Latest',
	'尿素氮_Latest', '血红蛋白_Latest', '白细胞计数_Latest', '尿蛋白_Latest',
	'白细胞计数(平均)', '红细胞计数(平均)', '血小板(平均)', '尿肌酐/尿蛋白(平均)',
	'总胆固醇(平均)', '甘油三酯(平均)', '高密度脂蛋白(平均)', '低密度脂蛋白(平均)',
	'总蛋白(平均)', '白蛋白(平均)', '血糖(平均)', '收缩压(平均)', '舒张压(平均)', 'GFR(平均)',
	'白细胞计数(初次)', '红细胞计数(初次)', '血小板(初次)', '尿肌酐/尿蛋白(初次)',
	'总胆固醇(初次)', '甘油三酯(初次)', '高密度脂蛋白(初次)', '低密度脂蛋白(初次)',
	'总蛋白(初次)', '白蛋白(初次)', '血糖(初次)', '收缩压(初次)', '舒张压(初次)', 'GFR(初次)',
	'白细胞计数(末次)', '红细胞计数(末次)', '血小板(末次)', '尿肌酐/尿蛋白(末次)',
	'总胆固醇(末次)', '甘油三酯(末次)', '高密度脂蛋白(末次)', '低密度脂蛋白(末次)',
	'总蛋白(末次)', '白蛋白(末次)', '血糖(末次)', '收缩压(末次)', '舒张压(末次)', 'GFR(末次)']

	let dataManageDownload = manageResult.map(item => headKeys.map(key => item[key]))

	const headMap = {
		egfrSlopeK: 'GFR Slope k',
		egfrSlopeB: 'GFR Slope b',
		GFR_Latest: 'GFR Latest',
		CKD_Latest: 'CKD Latest',
		CKD_Change: 'CKD分期变化',
		scr_1: '预计进入透析时间',
		hbAverage: '血红蛋白控制值',
		hbAverageStd: '血红蛋白控制值是否达标',
		uaAverage: '尿酸控制值',
		uaAverageStd: '尿酸控制值是否达标',
		'肌酐_Latest': '肌酐 Latest',
		'尿酸_Latest': '尿酸 Latest',
		'尿素氮_Latest': '尿素氮 Latest',
		'血红蛋白_Latest': '血红蛋白 Latest',
		'白细胞计数_Latest': '白细胞计数 Latest',
		'尿蛋白_Latest': '尿蛋白 Latest',
	}

	const headTitle = headKeys.map(item => headMap[item] || item)
	dataManageDownload.unshift(headTitle)

	let bufferManage = xlsx.build([{
		name : 'sheet1',
		data: dataManageDownload
	}]);
	fs.writeFile('./manage.xlsx', bufferManage, function (err){
		if (err)
			throw err;
		console.log('Write to xls has finished'); 
	})

	let dataControlDownload = controlResult.map(item => headKeys.map(key => item[key]))
	dataControlDownload.unshift(headTitle)

	let bufferControl = xlsx.build([{
		name : 'sheet1',
		data: dataControlDownload
	}]);
	fs.writeFile('./control.xlsx', bufferControl, function (err){
		if (err)
			throw err;
		console.log('Write to xls has finished');
	})
}

function downloadTargetFile() {
	var targetKeys = ['收缩压', '舒张压', '体重(kg)', '钾', '钠', '氯', '钙', '磷', 'PTH', 'ALP',
	'WBC(白细胞计数)', 'RBC(红细胞计数)', 'Hb(血红蛋白)', 'PLT（血小板计数）', 'ALT(谷丙转氨酶)',
	'AST(谷草转氨酶)', 'TP(总蛋白)', 'ALB(白蛋白)', 'GLB(球蛋白)', 'BUN(尿素)', 'Scr(血肌酐)',
	'UA(尿酸)', 'GLU(血糖)', 'TC(总胆固醇)', 'TG(甘油三酯)', '高密度脂蛋白（HDL-C）', '低密度脂蛋白（LDL-C）',
	'HSCRP', '糖化血红蛋白（HbA1C）', '尿蛋白', '尿红细胞', '尿白细胞', '24h尿蛋白', '尿肌酐／尿蛋白']

	let headerKeys = ['组别', '姓名', '序号', '出生日期', '性别', '糖尿病', '高血压', '身高', 'RRT']
	

	targetKeys.forEach(item => {
		headerKeys.push('首次' + item)

		let i = 1
		while(i <= span3MonthMax) {
			headerKeys.push(i * 3 + '月' + item)
			i++
		}
	})

	let j = 1
	while(j <= spanYearMax) {
		headerKeys.push(j * 12 + '月预计进入透析时间')
		j++
	}
	
	let targetData  = [headerKeys]
	
	targetData.push(...targetResult.map(item => headerKeys.map(key => item[key] == null ? null : item[key])))

	let bufferTarget = xlsx.build([{
		name : 'sheet1',
		data: targetData
	}]);
	fs.writeFile('./target.xlsx', bufferTarget, function (err){
		if (err)
			throw err;
		console.log('Write to xls has finished'); 
	})
}

function dataInitialize() {
	calculateManageData()
	calculateControlData()
	calcIndicatorGather()
	calcDataStatistics()
	calcTValue()
	calcCKDProgress()
	// downloadFile()

	downloadTargetFile()
}

setTimeout(() => {
	dataInitialize()
}, 60);


router.get('/data', function(req, res, next) {
	res.json({
		"status": 1,
		"data": {
			manage: manageResult,
			control: controlResult
		},
	});
});

router.get('/statistics', function(req, res, next) {
	res.json({
		"status": 1,
		"data": {
			CKD_Progress,
			pValue: P_VALUE,
			manage: manageStatisticsResult,
			control: controlStatisticsResult,
		},
	});
});


router.get('*', function(req, res, next) {
	res.sendfile(path.join(__dirname, '../../public/index.html')); // 发送静态文件
});


module.exports = router;
